package ai.loa;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import ai.loa.ai.LOAAIPlayer;
import ai.loa.ai.LOABoardConstants;
import ai.loa.ai.Mossa;
import ai.loa.ai.RemotePlayer;
import ai.loa.ai.Stato;
import ai.loa.controller.LOAController;
import ai.loa.controller.LOAGameObserver;
import ai.loa.utility.IndependentFeatures;
import ai.loa.utility.Parser;
import ai.loa.utility.SyntaxException;
import ai.loa.utility.TraspositionTables;

public class LOAMain {

	static class GameThread implements LOAGameObserver {

		LOAController controller;

		public GameThread(LOAController controller) {
			this.controller = controller;
		}

		@Override
		public void turnChanged(Stato stato) {
			System.out.println("Scrivi la Mossa:\n");
			Scanner sc = new Scanner(System.in);
			String mossa = sc.nextLine();
			if (mossa.equals("save")) {
				IndependentFeatures.save();
				System.exit(1);
			}
			try {
				Mossa m = Parser.parse(mossa, controller.stato.board);
				controller.doMove(m);
			} catch (SyntaxException e) {
				e.printStackTrace();
			}
		}

	}

	public static void main(String[] args) throws Exception {
		// System.setOut(new PrintStream(new File(
		// "C:/Users/Giuseppe/Desktop/prova.txt")));
		Class.forName("ai.loa.ai.Mossa");
		Class.forName("ai.loa.utility.ConstantValues");
		Class.forName("ai.loa.Parameters");
		Class.forName("ai.loa.utility.IndependentFeatures");

		// Get the jvm heap size.
		long heapSize = Runtime.getRuntime().totalMemory();

		// Print the jvm heap size.
		System.out.println("Heap Size = " + heapSize);

		// non usare singleton ma variabile statica
		TraspositionTables.getInstance();
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		int locale = JOptionPane.showConfirmDialog(frame,
				"Vuoi giocare in locale ?", "", JOptionPane.YES_NO_OPTION);

		if (locale == JOptionPane.NO_OPTION) {
			String colore = "";
			Object playerColour = JOptionPane.showInputDialog(null,
					"Giocatore", "", JOptionPane.QUESTION_MESSAGE, null,
					new Object[] { "Bianco", "Negro" }, 0);
			if (playerColour == null) {
				return;
			}
			colore = (String) playerColour;
			frame.setTitle(colore);
			Object port = JOptionPane.showInputDialog(null, "Inserire porta",
					50001);
			int porta = Integer.parseInt((String) port);

			if (colore.equals("Bianco")) {
				ServerSocket ss = new ServerSocket(porta);
				Socket s = ss.accept();
				LOAController controller = new LOAController(
						LOABoardConstants.PLAYER_1);

				LOAAIPlayer ai = new LOAAIPlayer(controller);
				controller.setObserver(ai, LOABoardConstants.PLAYER_1);
				RemotePlayer rp = new RemotePlayer(s, controller);
				controller.setObserver(rp, LOABoardConstants.PLAYER_2);
				rp.start();

				controller.startGame();
			} else {
				Object address = JOptionPane.showInputDialog(null,
						"Inserire host", "localhost");
				Socket s = new Socket(address.toString(), porta);

				LOAController controller = new LOAController(
						LOABoardConstants.PLAYER_1);

				LOAAIPlayer ai = new LOAAIPlayer(controller);
				controller.setObserver(ai, LOABoardConstants.PLAYER_2);
				RemotePlayer rp = new RemotePlayer(s, controller);
				controller.setObserver(rp, LOABoardConstants.PLAYER_1);
				rp.start();

				controller.startGame();
			}

			// controller.setObserver(view, Pod.PLAYER_1);
		} else {
			String colore = "";
			Object playerColour = JOptionPane.showInputDialog(null,
					"Giocatore", "", JOptionPane.QUESTION_MESSAGE, null,
					new Object[] { "Bianco", "Negro" }, 0);
			if (playerColour == null) {
				return;
			}
			colore = (String) playerColour;
			frame.setTitle(colore);

			if (colore.equals("Bianco")) {
				LOAController controller = new LOAController(
						LOABoardConstants.PLAYER_1);
				LOAAIPlayer ai = new LOAAIPlayer(controller);

				GameThread g = new GameThread(controller);
				controller.setObserver(g, LOABoardConstants.PLAYER_1);
				controller.setObserver(ai, LOABoardConstants.PLAYER_2);
//				ai.change();
				System.out.println("Scrivi la Mossa:\n");
				Scanner sc = new Scanner(System.in);
				String mossa = sc.nextLine();
				try {
					Mossa m = Parser.parse(mossa, controller.stato.board);
					controller.doMove(m);
				} catch (SyntaxException e) {
					e.printStackTrace();
				}

			} else {
				LOAController controller = new LOAController(
						LOABoardConstants.PLAYER_1);
				LOAAIPlayer ai = new LOAAIPlayer(controller);
				GameThread g = new GameThread(controller);
				controller.setObserver(ai, LOABoardConstants.PLAYER_1);
				controller.setObserver(g, LOABoardConstants.PLAYER_2);
//				ai.change();
				controller.startGame();
//				System.out.println("Scrivi la Mossa:\n");
				Scanner sc = new Scanner(System.in);
				String mossa = sc.nextLine();
				try {
					Mossa m = Parser.parse(mossa, controller.stato.board);
					controller.doMove(m);
				} catch (SyntaxException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
